<template>
  <div>
    <h1>shp文件解析测试</h1>
    <el-upload ref="upload" action="" :auto-upload="false" accept="shp" :show-file-list="false" :on-change="bind">
      <el-input style="vertical-align: middle;" v-model="fileName" disabled placeholder="所选文件名">
      </el-input>
      <el-button size="small" type="primary" style="border-radius:0;vertical-align: middle;">
        选择文件
      </el-button>
      <div class="colorYellow">只能上传shp文件</div>
    </el-upload>
    WKT
    <el-input type="textarea" v-model="wkt" rows="10"></el-input>
    GeoJSON
    <el-input type="textarea" v-model="geoJSON" rows="10"></el-input>
  </div>
</template>

<script>
import {open} from 'shapefile' // 解析shp文件
import {convertToWK, parseFromWK} from 'wkt-parser-helper' // wkt与geojson互转
import * as turf from '@turf/turf'

export default {
  name: 'HelloWorld',
  data() {
    return {

      // 上传文件
      uploadShpFile: {},
      shpFileGeojson: null,
      featureCollection: {},
      fileName: '', //所选上传文件名
      wkt: '',
      geoJSON: '',
    };
  },
  methods: {
    /**
     * 绑定文件
     *
     * @param {*} files 文件
     * @param {*} fileList
     */
    async bind(files, fileList) {
      let file = files;
      if (!file) {
        return
      }
      this.fileName = file.name;
      let wkt = await this.readShpFile2WKT(file);
      console.log(wkt)
      this.wkt = wkt
      let json = parseFromWK(wkt);
      this.geoJSON = JSON.stringify(json, null, 4)
    },

    /**
     * 将shp文件读取为wkt (仅读取范围信息)
     *
     * @param shpFile
     */
    readShpFile2WKT(shpFile) {
      return new Promise((resolve, reject) => {
        this.readShpFile2GeoJSONArr(shpFile).then(geoJSONArr => {
          // 合并json
          let geoJSON, wkt = null;
          if (geoJSONArr && geoJSONArr.length > 0) {
            for (let i = 0; i < geoJSONArr.length; i++) {
              let json = geoJSONArr[i]
              if (geoJSON == null) {
                geoJSON = json
              } else {
                geoJSON = turf.union(geoJSON, json);
              }
            }
            if (geoJSON) {
              wkt = convertToWK(geoJSON);
            }
          }
          return resolve(wkt)
        }).catch(e => {
          return reject(e);
        })
      })
    },
    /**
     * 读取shp文件, 解析为geoJSON数组
     *
     * @param {*} shpFile shp文件
     */
    readShpFile2GeoJSONArr(shpFile) {
      return new Promise((resolve, reject) => {

        const name = shpFile.name
        const extension = name.split('.')[1]

        if (!extension || extension.toLowerCase() != 'shp') {

          return reject(new Error('文件不是shp文件！请重新选择文件'));

        } else {

          // 开始读取shp文件
          const reader = new FileReader()

          reader.readAsArrayBuffer(shpFile.raw)

          // 文件读取完毕事件钩子
          reader.onload = (event) => {

            // 定义GeoJSON数组, 一个shp里会有多个面, 即有多个geometry
            let geoJSONArr = []

            // 打开shp文件
            open(event.target.result).then((source) => {
                  source.read().then(
                      // 记录一条数据
                      function log(result) {
                        // 判断是否读取完毕
                        if (result.done) {
                          return resolve(geoJSONArr);
                        }
                        // 记录一行数据
                        let json = result.value
                        geoJSONArr.push(json)

                        // 递归, 读取下一行数据
                        source.read().then(log)
                      }
                  )
                }
            ).catch(error => {
              return reject(error);
            })
          }
        }
      });

    },
  }
}
</script>

<style scoped>
</style>
